#lang rosetta-racket


(require "utils.rkt")

(provide (struct-out board)
         make-board
         board-ref
         board-set
         board-set-vals)


(define (board-print board port mode)
  (for ((y (: (board-ny board))))
    (for ((x (: (board-nx board))))
      (write-string (format "~A" (board-ref board x y)) port))
    (unless (= y (- (board-ny board) 1))
      (newline port))))

(struct board (ns nx ny)
  #:constructor-name new-board
  #:property prop:custom-write board-print)

(define (make-board nx ny)
  (new-board (make-vector (* nx ny) 0) nx ny))

(define (board-pos board x y)
  (+ x (* y (board-nx board))))

(define (board-ref board x y)
  (vector-ref (board-ns board) (board-pos board x y)))

(define (board-set b x y val)
  (struct-copy board b (ns (vector-set (board-ns b) (board-pos b x y) val))))

(define (board-set-vals b xys vals)
  (struct-copy board b (ns (vector-set-vals (board-ns b) (map (match-lambda ((list x y) (board-pos b x y))) xys) vals))))